package spittr.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.crypto.password.StandardPasswordEncoder;

import javax.sql.DataSource;


@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    public DataSource dataSource;



    /**
     * 配置用户登录认证功能
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        //配置基于内存的用户存储(开发与测试)
       /* auth.inMemoryAuthentication()
                .withUser("user").password("password").roles("USER")
                .and()
                .withUser("admin").password("password").roles("USER","ADMIN");*/

        //配置基于数据库的用户存储
        auth.jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery("select username,password,true from Spitter where username = ?" )
                .authoritiesByUsernameQuery("select username,'ROLE_USER' from spitter where username = ?")
                .passwordEncoder(new StandardPasswordEncoder("dujiang"));

    }


    /**
     * 为具体请求设置细颗粒度的权限控制
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().loginPage("/login")//指定登录相关配置

                .and()
                .rememberMe().tokenValiditySeconds(2*7*24*60*60).key("spitttrKey")//使用cooike实现rememberme功能

                .and()
                .logout().logoutSuccessUrl("/login").logoutUrl("/logout")//设置登出配置，登出请求为/logout，登出成功后后请求为/login

                .and()
                .authorizeRequests()//为请求添加细颗粒度验证
                .antMatchers("/spitter/{username}").authenticated()
                .antMatchers("/spitters/me").access("hasRole('ROLE_USER') and hasIpAddress('192.168.0.11')")//验证/spitters/me请求(同时对请求与角色限制)
                .antMatchers("/spitter/register").authenticated()//验证/spitter/register请求
                .antMatchers(HttpMethod.POST,"/spittles").authenticated()//验证/spittles请求
                .anyRequest().permitAll()//其余请求无需验证

                .and()
                .requiresChannel()//设置http与https
                .antMatchers("/spitter/register").requiresSecure()//此请求需要使用https
                .anyRequest().requiresInsecure();//其他请求不要https







        //authenticated()表示必须登录才能执行该操作
        //permitAll()表示不登录也可以操作

        //http.csrf().disable();//禁用csrf保护(即跨站点攻击保护),开启csrf保护之后，logot必须为post请求。
    }
}
